package com.interfaces.pay;

import com.github.binarywang.wxpay.v3.util.SignUtils;
import com.interfaces.config.ProjectConfig;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.sign.Base64;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.service.payments.app.AppService;
import com.wechat.pay.java.service.payments.app.model.Amount;
import com.wechat.pay.java.service.payments.app.model.PrepayRequest;
import com.wechat.pay.java.service.payments.app.model.PrepayResponse;
import com.wechat.pay.java.service.payments.app.model.SceneInfo;

import java.io.FileInputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.Signature;
import java.util.HashMap;
import java.util.Map;

public class WxAppPay {
    public static Map<String,Object> pay(String title, String outTradeNo, BigDecimal money){
        Map result=new HashMap();
        money=money.multiply(new BigDecimal(100));

        // 使用微信支付公钥的RSA配置
        Config config = new RSAAutoCertificateConfig.Builder()
                        .merchantId(ProjectConfig.WxPayInit.MCHID)
                        .privateKeyFromPath(ProjectConfig.WxPayInit.privateKeyPath)
                        .merchantSerialNumber(ProjectConfig.WxPayInit.serialNumber)
                        .apiV3Key(ProjectConfig.WxPayInit.v3key)
                        .build();
        // 构建service
        AppService service = new AppService.Builder().config(config).build();
        // request.setXxx(val)设置所需参数，具体参数可见Request定义
        PrepayRequest request = new PrepayRequest();
        request.setAppid(ProjectConfig.WxPayInit.APPID);
        request.setMchid(ProjectConfig.WxPayInit.MCHID);
        SceneInfo sceneInfo=new SceneInfo();
        sceneInfo.setPayerClientIp("101.37.20.4");
        request.setSceneInfo(sceneInfo);
        Amount amount = new Amount();
        amount.setTotal(money.intValue());
        request.setAmount(amount);
        request.setDescription(title);
        request.setNotifyUrl(ProjectConfig.WxPayInit.notifyUrl);
        request.setOutTradeNo(outTradeNo);
        // 调用下单方法，得到应答
        PrepayResponse response = service.prepay(request);
        if(StringUtils.isNotEmpty(response.getPrepayId())){
            String timestamp = String.valueOf(System.currentTimeMillis() / 1000L);
            String nonceStr = SignUtils.genRandomStr();
            String prepayId=response.getPrepayId();
            String sign=getSignApp("POST","/v3/pay/transactions/app",timestamp,nonceStr,prepayId);
            result.put("sign",sign);
            result.put("timestamp",timestamp);
            result.put("noncestr",nonceStr);
            result.put("package","Sign=WXPay");
            result.put("prepayid",prepayId);
            result.put("sign_type","HMAC-SHA256");
            result.put("partnerid",ProjectConfig.WxPayInit.MCHID);
            result.put("appid",ProjectConfig.WxPayInit.APPID);
            return result;
        }
        return null;

    }

    public static String getSignApp(String requestType, String url,String timestamp,String nonceStr,String prepayId) {
        StringBuilder signContent = new StringBuilder();
//        signContent.append(requestType).append("\n");
//        signContent.append(url).append("\n");
        signContent.append(ProjectConfig.WxPayInit.APPID).append("\n");
        signContent.append(timestamp).append("\n");
        signContent.append(nonceStr).append("\n");
        signContent.append(prepayId).append("\n");
        return sha256sign(signContent.toString());
    }
    public static String sha256sign(String message){
        try {
            Signature signature = Signature.getInstance("SHA256withRSA");
            signature.initSign(getPrivateKey());
            signature.update(message.getBytes());
            return new String(Base64.encode(signature.sign()));
        }catch (Exception e){
            throw new RuntimeException(e.getMessage());
        }

    }
    public static PrivateKey getPrivateKey()  {
        try {
            String p12Path=ProjectConfig.WxPayInit.keyPath;
            String p12Password=ProjectConfig.WxPayInit.MCHID;
            // 初始化KeyStore
            KeyStore keyStore = KeyStore.getInstance("PKCS12");
            try (InputStream is = new FileInputStream(p12Path)) {
                keyStore.load(is, p12Password.toCharArray()); // 加载p12文件
            }

            // 获取私钥的别名，通常别名是证书的别名
            String keyAlias = keyStore.aliases().nextElement(); // 通常只有一个条目，即私钥条目
            PrivateKey privateKey = (PrivateKey) keyStore.getKey(keyAlias, p12Password.toCharArray());
            return privateKey;
        }catch (Exception e){
            System.err.println("P12证书加载异常");
            throw new RuntimeException(e.getMessage());
        }
    }
}
